package com.str.intro;
public class Date2 implements Date {
  // Each Date value is a past, present, or future date.

  // This date is represented by a year number y, and a day-in-year
  // number d (1 <= d <= year length <= 366).
  private int year;
  private int day;

// Constructor
  public Date2(int y, int m, int d) {
    // Construct a date with year y, month m, and day-in-month d.
    // Throw an exception if they constitute an improper date.
    if (m < 1 || m > 12 || d < 1 || d > length(m, y))
      throw new IllegalArgumentException("Improper date");
    for (int i = 1; i < m; i++)
      d += length(i, y);
    year = y;
    day = d;
  } // end Date2 constructor

// Modifier
  public void advance(int n) {
    // Advance this date by n days (where n >= 0).
    day += n;
    int last;
    while (day > (last = (isLeap(year) ? 366 : 365))) {
      day -= last;
      year++;
    }
  }

// Accessor
  public String toString() {
    // Return this date's ISO string representation.
    int m = 1, d = day;
    int last;
    while (d > (last = length(m, year))) {
      d -= last;
      m++;
    }
    return year + "-" + m + "-" + d;
  }

// Auxiliary methods
  private int length(int m, int y) {
    // Return the number of days in month m in year y.
    switch (m) {
      case 1: case 3: case 5: case 7:
      case 8: case 10: case 12:
        return 31;
      case 4: case 6: case 9: case 11:
        return 30;
      case 2:
        return (isLeap(y) ? 29 : 28);
      default:
        return -1;
    }
  }

  private boolean isLeap(int y) {
    // Return true if and only if y is a leapyear.
    return (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0));
  }
} // end class Date2
